import { Injectable } from '@angular/core';
import { Todo } from './todo.model';
import { BehaviorSubject, Observable } from 'rxjs';


export const enum TodoFilter {
  Active = 'active',
  Completed = 'completed'
}

@Injectable({
  providedIn: 'root'
})
export class TodoService {

  private latestId = 0;

  // private todoList: Todo[] = [];

  private readonly todos: BehaviorSubject<Todo[]> = new BehaviorSubject<Todo[]>([]);
  todos$: Observable<Todo[]> = this.todos.asObservable();

  // private readonly count: BehaviorSubject<number> = new BehaviorSubject<number>(0);
  // count$: Observable<number> = this.count.asObservable();

  constructor() { }

  add(content: string): Todo {
    const trimmed = content.trim();
    if (trimmed.length > 0) {
      const todo = {
        id: ++this.latestId,
        content,
        completed: false,
        editing: false
      };
      // this.todoList.push(todo);
      const todoList = this.todos.getValue();
      todoList.push(todo);
      this.todos.next(todoList);
      // this.count.next(this.todoList.length);
      return todo;
    } else {
      return null;
    }
  }

  update(data: Partial<Todo>): Todo {
    const todos = this.todos.getValue();
    const index = todos.findIndex(it => it.id === data.id);
    if (index >= 0) {
      const matched = todos[index];
      const newTodo = {
        ...matched,
        ...data
      };
      const todoList = [
        ...todos.slice(0, index),
        newTodo,
        ...todos.slice(index + 1)
      ];
      this.todos.next(todoList);
      return newTodo;
    } else {
      return null;
    }
  }

  updateAllComplete(completed?: boolean): Todo[] {
    const todoList = this.todos.getValue();
    const uncompletedTodos = todoList.filter(it => !it.completed);
    todoList
      .forEach(it => {
        it.completed = completed !== undefined ? completed : uncompletedTodos.length > 0;
      });
    this.todos.next(todoList);
    return todoList;
  }

  remove(id: number): Todo {
    const todoList = this.todos.getValue();
    const todo = todoList.find(it => it.id === id);
    this.todos.next(todoList.filter(it => it.id !== id));
    // this.count.next(this.todoList.length);
    return todo;
  }

  filter(filter: TodoFilter): Todo[] {
    const todoList = this.todos.getValue();
    return todoList.filter(it => {
      if (filter === TodoFilter.Active) {
        return !it.completed;
      } else if (filter === TodoFilter.Completed) {
        return it.completed;
      } else {
        return true;
      }
    });
  }

}
